1 
2 
3 /*
4 Boiler plate for irp cancelation, for irp queues you manage yourself
5 -Gunnar
6 */
7 
8 
9 
10 CancelRoutine(
11    DEV_OBJ Dev,
12    Irp
13    )
14 {
15    //don't need this since we have our own sync. protecting irp cancellation
16    IoReleaseCancelSpinLock(Irp->CancelIrql);
17 
18    theLock = Irp->Tail.Overlay.DriverContext[3];
19 
20    Lock(theLock);
21    RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
22    Unlock(theLock);
23 
24    Irp->IoStatus.Status = STATUS_CANCELLED;
25    Irp->IoStatus.Information = 0;
26 
27    IoCompleteRequest(Irp, IO_NO_INCREMENT);
28 
29 }
30 
31 
32 QUEUE_BOLIERPLATE
33 {
34    Lock(theLock);
35 
36    Irp->Tail.Overlay.DriverContext[3] = &theLock;
37 
38    IoSetCancelRoutine(Irp, CancelRoutine);
39    if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
40    {
41       /*
42       Irp has already been cancelled (before we got to queue it),
43       and we got to remove the cancel routine before the canceler could,
44       so we cancel/complete the irp ourself.
45       */
46 
47       Unlock(theLock);
48 
49       Irp->IoStatus.Status = STATUS_CANCELLED;
50       Irp->IoStatus.Information = 0;
51       IoCompleteRequest(Irp, IO_NO_INCREMENT);
52 
53       return FALSE;
54    }
55 
56    //else were ok
57 
58 
59    Irp->IoStatus.Status = STATUS_PENDING;
60    IoMarkIrpPending(Irp);
61 
62    InsertTailList(Queue);
63 
64    Unlock(theLock);
65 
66 }
67 
68 
69 DEQUEUE_BOILERPLATE
70 {
71    Lock(theLock);
72 
73    Irp = RemoveHeadList(Queue);
74 
75    if (!IoSetCancelRoutine(Irp, NULL))
76    {
77       /*
78       Cancel routine WILL be called after we release the spinlock. It will try to remove
79       the irp from the list and cancel/complete this irp. Since we allready removed it,
80       make its ListEntry point to itself.
81       */
82 
83       InitializeListHead(&Irp->Tail.Overlay.ListEntry);
84 
85       Unlock(theLock);
86 
87       return;
88    }
89 
90 
91    /*
92    Cancel routine will NOT be called, canceled or not.
93    The Irp might have been canceled (Irp->Cancel flag set) but we don't care,
94    since we are to complete this Irp now anyways.
95    */
96 
97    Unlock(theLock);
98 
99    Irp->IoStatus.Status = STATUS_SUCCESS;
100    Irp->IoStatus.Information = 0;
101    IoCompleteRequest(Irp, IO_NO_INCREMENT);
102 
103 }
104